home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / ImageWriterLQ (alt. rdip) / DialogRoutines.c < prev    next >
Encoding:
Text File  |  1995-04-10  |  22.1 KB  |  812 lines  |  [TEXT/MPS ]

  1. /*---------------------------------------------------------------------------
  2. FILENAME
  3.     DialogRoutines.c
  4.  
  5. DESCRIPTION
  6.     This file contains the routines which are used to process the LQ driver's
  7.     sheetfeeder dialog.
  8.         
  9. COPYRIGHT
  10.     Copyright Apple Computer, Inc. 1992-1994
  11.     All rights reserved. 
  12.     
  13. INTERFACE ROUTINES:
  14.     DoSheetfeederDialog
  15.  
  16.     12/20/93        dmh                Sync'd with the shipping 1.0b3 GX driver.
  17.      8/28/94        dmh                Sync'd with the shipping 1.0.1 GX driver.
  18.  
  19. -------------------------------------------------------------------------------- */
  20.  
  21. // Include the standard Mac header files 
  22. #include "MacIncludes.h"
  23.  
  24. // Include the new QuickDraw GX graphics header files 
  25. #include <graphics routines.h>
  26. #include <graphics libraries.h>
  27. #include <math routines.h>
  28. #include <qd library.h>
  29.  
  30. // Include the required Printing Manager header files 
  31. #include <PrintingManager.h>
  32. #include <PrintingMessages.h>
  33. #include <PrintingDrivers.h>
  34. #include <Collections.h>
  35. #include <Messages.h>
  36. #include <PrintingResTypes.h>
  37. #include <PrintingErrors.h>
  38.  
  39. #include <GXExceptions.h>
  40.  
  41. // Include the internal driver constants and types used by this module 
  42. #include "Resources.h"
  43. #include "UniversalMessageIntf.h"
  44. #include "DialogRoutines.h"
  45.  
  46.  
  47. /***************************************************************************************
  48. *                                                 CONSTANTS                                                         *
  49. ***************************************************************************************/                        
  50.  
  51. // Constants for accessing items in the Sheetfeeder dialog
  52.  
  53. #define    kTray1Item                4            //    Tray #1 pop-up menu
  54. #define    kTray2Item                5            //    Tray #2 pop-up menu
  55. #define    kTray3Item                6            //    Tray #3 pop-up menu
  56. #define    kPrinterPICTItem        7            //    Picture of the printer with a sheetfeeder
  57.  
  58. // Constants useful for filtering events
  59.  
  60. #define    kENTER                    0x03        // ENTER character
  61. #define    kCR                        0x0D        // Carriage return character
  62.  
  63. // Constants defining the maximum paper size supported by the LQ printer
  64.  
  65. #define    kMaxPaperWidth            ff(15)    // 15 inches is maximum width
  66. #define    kMaxPaperHeight        ff(69)    // 69 inches is maximum height
  67.  
  68.  
  69. /*********************************************************************************
  70.  *                                             TYPES                                                     *
  71.  *********************************************************************************/
  72.  
  73. // PopupMenuInfo - Structure used to initialize the tray pop-up menus 
  74.  
  75. typedef struct
  76. {
  77.     short                numTrays;        // Number of trays configured on the printer 
  78.     MenuHandle        tray1Menu;        //    handle to the tray #1 pop-up menu
  79.     MenuHandle        tray2Menu;        //    handle to the tray #2 pop-up menu
  80.     MenuHandle        tray3Menu;        //    handle to the tray #3 pop-up menu
  81. }    PopupMenuInfo,
  82.     *PopupMenuInfoPtr;
  83.     
  84.     
  85. // PaperSearchRec - Structure used to search for a paper type chosen from a pop-up menu
  86.  
  87. typedef struct
  88. {
  89.     gxPaperType        paper;            // temp. paper type reference in which to return found paper type 
  90.     Str31                paperName;        //    name of the paper to locate
  91. }    PaperSearchRec,
  92.     *PaperSearchRecPtr;
  93.     
  94.  
  95. /***************************************************************************************
  96. *                                         INLINE ROUTINES                                                         *
  97. ***************************************************************************************/                        
  98.  
  99. pascal void QDDrawPicture(PicHandle myPicture,const Rect *dstRect) = 0xA8F6;
  100.  
  101.  
  102. /***************************************************************************************
  103. *                                         INTERNAL ROUTINES                                                     *
  104. ***************************************************************************************/                        
  105.  
  106.  
  107. /****************************************************************************************
  108.  
  109.                             FindChosenPaperType
  110.                             
  111.     function:
  112.                 This routine is called by ForEachPaperTypeDo, and it searches for a specific
  113.                 paper type (by name).  It terminates searching when the paper type is 
  114.                 found.  Only the names of paper that will fit into the printer will be considered.
  115.  
  116.                 
  117.     parameters:                
  118.                 paper                target paper type
  119.                 paperToFind        structure that identifies the paper type to find
  120.                 
  121.     returns:
  122.                 LoopStatus        keepLooping => keep examining paper types
  123.                                     stopLooping    => no longer loop - we found the one we wanted
  124.     
  125. ****************************************************************************************/
  126. pascal gxLoopStatus FindChosenPaperType(gxPaperType paper, PaperSearchRecPtr paperToFind)
  127. {
  128.     Str31                paperName;
  129.     gxLoopStatus    status = gxKeepLooping;
  130.     gxRectangle        paperSize;
  131.     
  132.     // Get the dimensions of the paper
  133.     GXGetPaperTypeDimensions(paper, nil, &paperSize);
  134.     
  135.     // Will the paper fit into the printer?
  136.     if (    ( (paperSize.right - paperSize.left) <= FixMul(ff(72), kMaxPaperWidth) )    &&
  137.             ( (paperSize.bottom - paperSize.top) <= FixMul(ff(72), kMaxPaperHeight) )
  138.         )
  139.     {
  140.         // Retrieve the name of the paper type
  141.         GXGetPaperTypeName(paper, paperName);
  142.     
  143.         if ( IUCompString(paperName, paperToFind->paperName) == 0 )    //    T => Found the paper type
  144.         {
  145.             // Make a copy of this paper type and quit searching
  146.             GXCopyPaperType (paper, paperToFind->paper);
  147.             status = gxStopLooping;
  148.         }
  149.     }
  150.         
  151.     return(status);
  152. /* FindChosenPaperType */
  153.  
  154.  
  155. /****************************************************************************************
  156.  
  157.                             SaveSheetfeederSettings
  158.                             
  159.     function:
  160.                 This routine is called if the user confirms the changes in the dialog.  It
  161.                 stores updates the tray information configuration file with the user's latest
  162.                 settings.
  163.                 
  164.     parameters:                
  165.                 theDlog        pointer to the target dialog
  166.                 menuStuff    info. about the pop-up menus
  167.                 
  168.     returns:
  169.                 OSErr            error code
  170.     
  171. ****************************************************************************************/
  172. OSErr SaveSheetfeederSettings(DialogPtr theDlog, PopupMenuInfoPtr menuStuff)
  173. {
  174.     OSErr            anErr;
  175.     gxPaperType    paper;
  176.     gxJob            theJob = GXGetJob();
  177.     MenuHandle    *nextMenu;
  178.     short            i;
  179.     
  180.     // Create a temporary paper type
  181.     
  182.     paper = GXNewPaperType(theJob, NULL, NULL, NULL);
  183.     anErr = GXGetJobError(theJob);
  184.     require(anErr == noErr, NewPaperType);
  185.     
  186.     // For each visible pop-up menu, update its associated tray information
  187.     
  188.     for (i = kTray1Item, nextMenu = &(menuStuff->tray1Menu); i <= kTray3Item; ++i, ++nextMenu )
  189.     {
  190.         short        whichTray = i - kTray1Item + 1;
  191.         
  192.         if ( whichTray <= menuStuff->numTrays )    //    T => This menu is visible
  193.         {
  194.             Str31                    paperName;
  195.             short                    itemType;
  196.             ControlHandle        item;
  197.             Rect                    itemRect;
  198.             PaperSearchRec        paperToFind;
  199.             
  200.             // Get the name of the chosen paper type from the menu
  201.             
  202.             GetDItem(theDlog, i, &itemType, (Handle *) &item, &itemRect);
  203.             GetItem(*nextMenu, GetCtlValue(item), paperName);
  204.  
  205.             // Get the tray information for this tray
  206.             
  207.             anErr = GXGetTrayPaperType(whichTray, paper);
  208.             if (anErr == resNotFound)
  209.                 anErr = noErr;
  210.             require(anErr == noErr, GetTrayPaperType);
  211.         
  212.             //    Get the referenced paper type
  213.  
  214.             paperToFind.paper = paper;
  215.             BlockMove((Ptr) paperName, (Ptr) paperToFind.paperName, sizeof(Str31));
  216.             
  217.             GXForEachJobPaperTypeDo(theJob, FindChosenPaperType, &paperToFind, false);        // Don't consider the format device in this search    
  218.             anErr = GXGetJobError(theJob);
  219.             require(anErr == noErr, ForEachPaperTypeDo);
  220.             
  221.             // Update the paper type for this tray
  222.             
  223.             anErr = GXSetTrayPaperType(whichTray, paper);
  224.             require(anErr == noErr, SetTrayPaperType);
  225.             
  226.         }
  227.         else    //     T => No more visible pop-up menus
  228.             break;
  229.     }
  230.  
  231.  
  232. /******* Clean-up *******/
  233.  
  234. SetTrayPaperType:
  235. GetTrayPaperType:
  236. ForEachPaperTypeDo:
  237.     GXDisposePaperType(paper);
  238.  
  239. NewPaperType:
  240.     return(anErr);
  241. }
  242. /* SaveSheetfeederSettings */
  243.  
  244.  
  245. /****************************************************************************************
  246.  
  247.                             SheetfeederDialogFilter
  248.                             
  249.     function:
  250.                 This routine is the filter proc. that is passed to ModalDialog when the 
  251.                 sheetfeeder dialog is displayed.  It filters for the <cr> and <enter> keys
  252.                 and for command-".".
  253.                 
  254.     parameters:                
  255.                 theDlog        pointer to the target dialog
  256.                 theEvent        the event to be filtered
  257.                 itemHit        the item which was selected; may be mapped to ok or cancel
  258.                 
  259.     returns:
  260.                 Boolean        true if we've filtered the event; false if ModalDialog should process it
  261.     
  262. ****************************************************************************************/
  263. pascal Boolean SheetfeederDialogFilter(DialogPtr theDlog, EventRecord *theEvent, short *itemHit)
  264. {
  265.     Boolean    eventFiltered = false;
  266.     short        itemType;
  267.     Rect        itemRect;
  268.     Handle    item;
  269.     
  270.     if ( (theEvent->what == keyDown) || (theEvent->what == autoKey) ) 
  271.     {
  272.         char        c;
  273.         
  274.         c = (char) (theEvent->message & charCodeMask);
  275.         
  276.         if ( (c == kCR) || (c == kENTER) )     //    T => User typed carriage return or enter key; filter event
  277.         {
  278.             *itemHit = ok;
  279.             eventFiltered = true;
  280.         }
  281.         else
  282.         if ( (c == '.') && ((theEvent->modifiers & cmdKey) != 0) )    //    T => User typed <cmnd>-"."
  283.         {
  284.             *itemHit = cancel;
  285.             eventFiltered = true;
  286.         }
  287.         
  288.         if (eventFiltered)    //    T => Highlight the buttons appropriately
  289.         {
  290.             ControlHandle    theCtrl;
  291.             long                ignore;
  292.             
  293.             // Highlight the OK button momentarily
  294.             
  295.             GetDItem(theDlog, *itemHit, &itemType, (Handle *) &theCtrl, &itemRect);
  296.             HiliteControl(theCtrl, inButton);
  297.             Delay(10, &ignore);
  298.             HiliteControl(theCtrl, 0);
  299.         }
  300.     }
  301.     else
  302.     if (theEvent->what == updateEvt)    //    T => Outline the OK button
  303.     {
  304.         GrafPtr    oldPort;
  305.         
  306.         GetPort(&oldPort);
  307.         SetPort(theDlog);
  308.         
  309.         GetDItem(theDlog, ok, &itemType, &item, &itemRect);
  310.         PenSize(3, 3);
  311.         InsetRect(&itemRect, -4, -4);
  312.         FrameRoundRect(&itemRect, 16, 16);
  313.         PenNormal();
  314.  
  315.         SetPort(oldPort);
  316.     }
  317.  
  318.     return(eventFiltered);
  319. }
  320. /* SheetfeederDialogFilter */
  321.  
  322.  
  323. /****************************************************************************************
  324.  
  325.                             UniquePaperName
  326.                             
  327.     function:
  328.                 This routine searches for a specified paper type name in a specific pop-up
  329.                 menu.  If it finds the name, the routine returns false; otherwise it
  330.                 returns true.
  331.                 
  332.     parameters:                
  333.                 hMenu            handle to the menu to examine
  334.                 paperName    name of the paper type to insert to check for
  335.                 
  336.     returns:
  337.                 Boolean        true if paper type name is unique; false otherwise
  338.     
  339. ****************************************************************************************/
  340. Boolean UniquePaperName(MenuHandle hMenu, Str31 paperName)
  341. {
  342.     Boolean    isUnique = true;
  343.     short        i;
  344.     Str255    menuString;
  345.     
  346.     for (i = CountMItems(hMenu); i > 0; --i) 
  347.     {
  348.         GetItem(hMenu, i, menuString);
  349.         
  350.         if ( IUCompString(paperName, menuString) == 0 )     //    T => Found the string
  351.         {
  352.             isUnique = false;
  353.             break;
  354.         }
  355.     }
  356.     
  357.     return(isUnique);
  358. }  
  359. /* UniquePaperName */
  360.  
  361.  
  362. /****************************************************************************************
  363.  
  364.                             AddPaperName
  365.                             
  366.     function:
  367.                 This routine is called by ForEachPaperTypeDo, and it adds a paper name to 
  368.                 each visible pop-up menu if the name does not already appear in the menu.
  369.                 Only the names of paper that will fit into the printer will be listed
  370.                 in the pop-up menu.
  371.                 
  372.     parameters:                
  373.                 paper                target paper type
  374.                 menuStuff        pointer to info about the dialog's pop-up menus
  375.                 
  376.     returns:
  377.                 LoopStatus        keepLooping => examine all target paper types
  378.     
  379. ****************************************************************************************/
  380. pascal gxLoopStatus AddPaperName(gxPaperType paper, PopupMenuInfoPtr menuStuff)
  381. {
  382.     Str31            paperName;
  383.     gxRectangle    paperSize;
  384.     
  385.     // Get the dimensions of the paper
  386.     GXGetPaperTypeDimensions(paper, nil, &paperSize);
  387.     
  388.     // Will the paper fit into the printer?
  389.     if (    ( (paperSize.right - paperSize.left) <= FixMul(ff(72), kMaxPaperWidth) )    &&
  390.             ( (paperSize.bottom - paperSize.top) <= FixMul(ff(72), kMaxPaperHeight) )
  391.         )
  392.     {
  393.         // Retrieve the name of the paper type
  394.         GXGetPaperTypeName(paper, paperName);
  395.     
  396.         if ( UniquePaperName(menuStuff->tray1Menu, paperName) )    //    T => If the paper name is unique, add it
  397.         {
  398.             MenuHandle        *nextMenu;
  399.             Str255            theName;
  400.             short                i;
  401.             
  402.             // For each visible menu, add the name to the pop-up
  403.             
  404.             for (i = kTray1Item, nextMenu = &(menuStuff->tray1Menu); i <= kTray3Item; ++i, ++nextMenu )
  405.             {
  406.                 if ( (i - kTray1Item + 1) <= menuStuff->numTrays )    //    T => This menu is visible
  407.                 {
  408.                     AppendMenu(*nextMenu, "\p ");
  409.                     BlockMove(paperName, theName, sizeof(Str31));
  410.                     SetItem(*nextMenu, CountMItems(*nextMenu), theName);
  411.                 }
  412.                 else    //     T => No more visible pop-up menus
  413.                     break;
  414.             }
  415.         }
  416.     }
  417.         
  418.     return (gxKeepLooping);
  419. /* AddPaperName */
  420.  
  421.  
  422. /****************************************************************************************
  423.  
  424.                             LoadPaperNames
  425.                             
  426.     function:
  427.                 This routine loads the names of each uniquely named paper type into each of the
  428.                 tray pop-up menus that are still visible.
  429.                 
  430.     parameters:                
  431.                 pDlg            Pointer to the target dialog
  432.                 whichItem    Index in the DITL of the item to draw
  433.                 
  434.     returns:
  435.                 OSErr            error code
  436.     
  437. ****************************************************************************************/
  438. OSErr LoadPaperNames(DialogPtr theDlog, PopupMenuInfoPtr menuStuff)
  439. {
  440.     short                itemType;
  441.     Rect                itemRect;
  442.     ControlHandle    item;
  443.     short                i;
  444.     gxJob                theJob = GXGetJob();
  445.     OSErr                anErr;
  446.  
  447.     GXForEachJobPaperTypeDo(theJob,  AddPaperName,  menuStuff, false);        // Don't consider the format device in this search    
  448.     anErr = GXGetJobError(theJob);
  449.  
  450.     if (anErr == noErr)
  451.     {
  452.         MenuHandle        *nextMenu;
  453.         
  454.         // For each visible menu, initialize the pop-up control
  455.         
  456.         for (i = kTray1Item, nextMenu = &(menuStuff->tray1Menu); i <= kTray3Item; ++i, ++nextMenu )
  457.         {
  458.             if ( (i - kTray1Item + 1) <= menuStuff->numTrays )    //    T => This menu is visible
  459.             {
  460.                 GetDItem(theDlog, i, &itemType, (Handle *) &item, &itemRect);
  461.                 
  462.                 SetCtlMin(item, 1);
  463.                 SetCtlMax(item, CountMItems(*nextMenu));
  464.                 SetCtlValue(item, 1);
  465.             }
  466.             else    //     T => No more visible pop-up menus
  467.                 break;
  468.         }
  469.     }
  470.  
  471.     return(anErr);
  472. }
  473. /* LoadPaperNames */
  474.  
  475.  
  476. /****************************************************************************************
  477.  
  478.                             SheetfeederDrawProc
  479.                             
  480.     function:
  481.                 This routine is used to draw the picture of the sheetfeeder in the configuration
  482.                 dialog.
  483.                 
  484.     parameters:                
  485.                 pDlg            Pointer to the target dialog
  486.                 whichItem    Index in the DITL of the item to draw
  487.                 
  488.     returns:
  489.                 OSErr            error code
  490.     
  491. ****************************************************************************************/
  492. pascal void SheetfeederDrawProc(WindowPtr    pDlg, short whichItem)
  493. {
  494.     SpecGlobalsHdl     hGlobals = GetMessageHandlerInstanceContext();
  495.     Handle                hItem;
  496.     Rect                    itemRect;
  497.     short                    itemType;
  498.     
  499.     GetDItem(pDlg, whichItem, &itemType, &hItem, &itemRect);
  500.  
  501.     QDDrawPicture((*hGlobals)->sheetFeederPICT, &itemRect);
  502. }
  503. /* SheetfeederDrawProc */
  504.  
  505.  
  506. /****************************************************************************************
  507.  
  508.                             GetConfigInfo
  509.                             
  510.     function:
  511.                 This routine is a utility function that returns the LQ driver's configuration
  512.                 info. from the desktop printer file.
  513.                 
  514.     parameters:                
  515.                 configInfo    Latest info fetched from the DTP file
  516.                 
  517.     returns:
  518.                 OSErr            error code
  519.     
  520. ****************************************************************************************/
  521. OSErr GetConfigInfo(IWLQConfigInfoPtr configInfo)
  522. {
  523.     OSErr                        anErr;
  524.     Str32                        deviceName;
  525.     IWLQConfigInfoHdl        hConfigData;
  526.     
  527.     // Get the name of the desktop printer file
  528.     GXGetPrinterName(GXGetJobOutputPrinter(GXGetJob()), deviceName);
  529.  
  530.     // Get the config info
  531.     anErr = GXFetchDTPData(deviceName, kIWLQConfigType, kIWLQConfigID, (Handle *) &hConfigData);
  532.     require(anErr == noErr, FetchDTPData);
  533.     
  534.     // Return the config. info
  535.     *configInfo = **hConfigData;
  536.     
  537.     // Kill the temporary handle
  538.     DisposHandle((Handle) hConfigData);
  539.     
  540.  
  541. /******* Clean-up *******/
  542.  
  543. FetchDTPData:
  544.     return(anErr);
  545. }
  546. /* GetConfigInfo */
  547.  
  548.  
  549. /****************************************************************************************
  550.  
  551.                             InitSheetfeederDialog
  552.                             
  553.     function:
  554.                 This routine is called to initialize the sheet feeder dialog and to set the
  555.                 state of the pop-up menus based upon the latest configuration information.
  556.                 
  557.     parameters:                
  558.                 theDlog        returns the pointer to the dialog window if init. was succesful; otherwise nil
  559.                 menuStuff    info about the dialog's pop-up menus
  560.                 
  561.     returns:
  562.                 OSErr        error code
  563.     
  564. ****************************************************************************************/
  565. OSErr InitSheetfeederDialog(DialogPtr *theDlog, PopupMenuInfoPtr menuStuff)
  566. {
  567.     OSErr                    anErr = noErr;
  568.     DialogPtr            dLog;
  569.     IWLQConfigInfo        configInfo;
  570.     SpecGlobalsHdl     hGlobals = GetMessageHandlerInstanceContext();
  571.     short                    itemType;
  572.     Rect                    itemRect;
  573.     Handle                hItem;
  574.     gxPaperType            paper;
  575.     
  576.     // Initialize variables
  577.     *theDlog = nil;
  578.     (*hGlobals)->sheetFeederPICT = nil;
  579.     
  580.     dLog = GetNewDialog(kSheetFeederDLOG, nil, (WindowPtr) (-1));
  581.     if (dLog == nil)
  582.     {
  583.         anErr = MemError();
  584.         if (anErr == noErr)
  585.             anErr = resNotFound;
  586.         
  587.         require(anErr == noErr, GetNewDialog);
  588.     }
  589.  
  590.     // Fetch the latest configuration info. from the DTP file
  591.     anErr = GetConfigInfo(&configInfo);
  592.     require(anErr == noErr, GetConfigInfo);
  593.     
  594.     // Determine which sheetfeeder picture to display in the dialog
  595.     {
  596.         short            whichPICT;
  597.         Handle        thePICT;
  598.         
  599.         switch (configInfo.numTrays)
  600.         {
  601.             case 1:    whichPICT = kOneTrayPICT;         break;
  602.             case 2:    whichPICT = kTwoTrayPICT;         break;
  603.             case 3:    whichPICT = kThreeTrayPICT;     break;
  604.         }
  605.         
  606.         anErr = Send_GXFetchTaggedDriverData('PICT', whichPICT, (Handle *) &thePICT);
  607.         require(anErr == noErr, FetchTaggedDriverData);
  608.         
  609.         // Save this handle in our globals
  610.  
  611.         HNoPurge(thePICT);
  612.         (*hGlobals)->sheetFeederPICT = (PicHandle) thePICT;
  613.         
  614.         // Setup the DrawProc for this picture item
  615.         
  616.         GetDItem(dLog, kPrinterPICTItem, &itemType, &hItem, &itemRect);
  617.         SetDItem(dLog, kPrinterPICTItem, itemType, (Handle) SheetfeederDrawProc, &itemRect);
  618.     }
  619.     
  620.     // Now fill in the pop-up menu paper type names and hide any pop-ups that don't apply
  621.     // to the current configuration
  622.     {
  623.         PopupPrivateDataHandle    privData;
  624.         short                            i;
  625.         MenuHandle                    *nextMenu;
  626.         
  627.         // Hide those pop-ups which don't apply to the current configuration
  628.         if (configInfo.numTrays < 3)
  629.         {
  630.             HideDItem(dLog, kTray3Item);
  631.         }
  632.  
  633.         if (configInfo.numTrays < 2)
  634.         {
  635.             HideDItem(dLog, kTray2Item);
  636.         }
  637.         
  638.         // Init. the menuStuff structure in order to load the paper names into the pop-ups
  639.         
  640.         menuStuff->numTrays = configInfo.numTrays;
  641.  
  642.         for (i = kTray1Item, nextMenu = &(menuStuff->tray1Menu); i <= kTray3Item; ++i, ++nextMenu)
  643.         {
  644.             GetDItem(dLog, i, &itemType, &hItem, &itemRect);
  645.             privData = (PopupPrivateDataHandle) (* (ControlHandle) hItem)->contrlData;
  646.             *nextMenu = (*privData)->mHandle;
  647.         }
  648.         
  649.         // Now load the paper type names into the remaining pop-up menus
  650.         anErr = LoadPaperNames(dLog, menuStuff);
  651.         require(anErr == noErr, LoadPaperNames);
  652.     }
  653.     
  654.     // Retrieve the latest paper<->tray configuration and force the pop-up(s) to display the
  655.     // correct paper name (i.e. the last selected paper name).
  656.     {
  657.         gxJob            theJob = GXGetJob();
  658.         MenuHandle    *nextMenu;
  659.         short            i;
  660.         
  661.         // Create a temporary paper type
  662.         
  663.         paper = GXNewPaperType(theJob, NULL, NULL, NULL);
  664.         anErr = GXGetJobError(theJob);
  665.         require(anErr == noErr, NewPaperType);
  666.         
  667.         // For each visible pop-up menu, try to display the last choosen paper type
  668.         
  669.         for (i = kTray1Item, nextMenu = &(menuStuff->tray1Menu); i <= kTray3Item; ++i, ++nextMenu )
  670.         {
  671.             short        whichTray = i - kTray1Item + 1;
  672.             
  673.             if ( whichTray <= menuStuff->numTrays )    //    T => This menu is visible
  674.             {
  675.                 Str255    menuString;
  676.                 short        j;
  677.                 Str31        paperName;
  678.                 
  679.                 // Get the tray information for this tray
  680.                 
  681.                 anErr = GXGetTrayPaperType(whichTray, paper);
  682.                 if (anErr == resNotFound)
  683.                     anErr = noErr;
  684.                 else {
  685.                     require(anErr == noErr, GetTrayPaperType);
  686.                 
  687.                     // Fetch the name of the paper type
  688.                     GXGetPaperTypeName(paper, paperName);
  689.                     
  690.                     // For each paper name in the menu, try to find a match
  691.                     
  692.                     for (j = CountMItems(*nextMenu); j > 0; --j) 
  693.                     {
  694.                         GetItem(*nextMenu, j, menuString);
  695.                         
  696.                         if ( IUCompString(paperName, menuString) == 0 )     //    T => Found the string
  697.                         {
  698.                             //    Make this paper name the current pop-up menu selection
  699.                             
  700.                             GetDItem(dLog, i, &itemType, &hItem, &itemRect);
  701.                             SetCtlValue((ControlHandle) hItem, j);
  702.                             break;
  703.                         }
  704.                     }
  705.                 }
  706.             }
  707.             else    //     T => No more visible pop-up menus
  708.                 break;
  709.         }
  710.  
  711.         // Dump the temporary paper type
  712.         GXDisposePaperType(paper);
  713.     }
  714.     
  715.     *theDlog = dLog;
  716.     
  717.     return(anErr);
  718.     
  719.     
  720. /******* Clean-up *******/
  721.  
  722. GetTrayPaperType:
  723.     GXDisposePaperType(paper);
  724.  
  725. NewPaperType:
  726. LoadPaperNames:
  727.     DisposHandle((Handle) (*hGlobals)->sheetFeederPICT);
  728.     
  729. FetchTaggedDriverData:
  730. GetConfigInfo:
  731.     DisposDialog(dLog);
  732.     
  733. GetNewDialog:
  734.     return(anErr);
  735. }
  736. /* InitSheetfeederDialog */
  737.  
  738.  
  739. /***************************************************************************************
  740. *                                         INTERFACE ROUTINES                                                     *
  741. ***************************************************************************************/                        
  742.  
  743. /****************************************************************************************
  744.  
  745.                             DoSheetfeederDialog
  746.                             
  747.     function:
  748.                 This routine is called to display and process the LQ driver's sheetfeeder
  749.                 dialog.  This dialog is displayed when the user selects the "Input Trays…" menu
  750.                 item from the Finder menu.  This dialog allows the user to specify the type
  751.                 of paper that's contained within the printer's sheet feeder.
  752.                 
  753.     parameters:                
  754.                 None
  755.                 
  756.     returns:
  757.                 OSErr        error code
  758.     
  759. ****************************************************************************************/
  760. OSErr DoSheetfeederDialog(void)
  761. {
  762.     OSErr                    anErr = noErr;
  763.     GrafPtr                oldPort;
  764.     DialogPtr            theDlog;
  765.     short                    itemHit = 0;
  766.     PopupMenuInfo        menuStuff;
  767.     SpecGlobalsHdl     hGlobals = GetMessageHandlerInstanceContext();
  768.     
  769.     GetPort(&oldPort);
  770.     
  771.     // Initialize the dialog before displaying it
  772.     anErr = InitSheetfeederDialog(&theDlog, &menuStuff);
  773.     require(anErr == noErr, InitSheetfeederDialog);
  774.     
  775.     // Make sure the dialog is now visible
  776.     ShowWindow(theDlog);
  777.     SelectWindow(theDlog);
  778.     
  779.     // Process events in the window
  780.     while ( (itemHit != ok) && (itemHit != cancel) )
  781.     {
  782.        ModalDialog((ModalFilterProcPtr) SheetfeederDialogFilter, &itemHit);
  783.     }
  784.  
  785.     //    Do we need to save the new settings?
  786.     if (itemHit == ok)
  787.         anErr = SaveSheetfeederSettings(theDlog, &menuStuff);
  788.         
  789.     // Dump the dialog and picture handle
  790.     
  791.     if ( (*hGlobals)->sheetFeederPICT != nil )
  792.         DisposHandle((Handle) (*hGlobals)->sheetFeederPICT);
  793.         
  794.     DisposDialog(theDlog);
  795.     
  796.     SetPort(oldPort);
  797.  
  798.     return(anErr);
  799.     
  800.     
  801. /******* Clean-up *******/
  802.  
  803. InitSheetfeederDialog:
  804.     SetPort(oldPort);
  805.     
  806.     return(anErr);
  807. }
  808. /* DoSheetfeederDialog */
  809.  
  810.